#include "stdafx.h"
#include "HelperWindow.h"
#include "OpacityUtils.hpp"

CHelperWindow::CHelperWindow(HINSTANCE hInstance, HWND hWnd) : m_hInstance(hInstance), m_hMainWnd(hWnd)
{
	const LPTSTR wndName = _T("WintcyHelperWindow");

	m_wmTaskbarCreated = RegisterWindowMessage(L"TaskbarCreated");

	WNDCLASS wndclass;
	SecureZeroMemory(&wndclass, sizeof(wndclass));

	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = RelayWndProc;
	wndclass.lpszClassName = wndName;

	if (!RegisterClass(&wndclass))
	{
		throw HelperWindowCreationException(_T("Failed to register window class."));
	}

	m_hwnd = CreateWindow(wndName, wndName, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, NULL, this);

	if (!m_hwnd)
	{
		throw HelperWindowCreationException(_T("Failed to create helper window."));
	}
}

LRESULT CALLBACK CHelperWindow::RelayWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	LONG_PTR pUserData = GetWindowLongPtr(hWnd, GWLP_USERDATA);
	if (pUserData)
	{
		CHelperWindow *pHelper = reinterpret_cast<CHelperWindow *>(pUserData);
		return pHelper->WndProc(hWnd, uMsg, wParam, lParam);
	}

	if (WM_NCCREATE == uMsg)
	{
		LPCREATESTRUCT pCS = (LPCREATESTRUCT)lParam;
		SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pCS->lpCreateParams);
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

HBITMAP GetOpaqueIcon(HINSTANCE hInstance)
{
	static HBITMAP hOpaqueBmp = nullptr;
	if (!hOpaqueBmp)
	{
		hOpaqueBmp = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BMPOPP));
	}
	return hOpaqueBmp;
}

HBITMAP GetTransparentIcon(HINSTANCE hInstance)
{
	static HBITMAP hTransparentBmp = nullptr;
	if (!hTransparentBmp)
	{
		hTransparentBmp = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BMPTRP));
	}
	return hTransparentBmp;
}

LRESULT CALLBACK CHelperWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	int   wmId;
	POINT pCursor;
	HMENU hMainMenu, hNotifyIconMenu;

	if (m_wmTaskbarCreated == uMsg)
	{
		OpacityUtils::FindTaskbars();
	}
	else
	{
		switch (uMsg)
		{
		case WM_USER + 1:
			if (WM_RBUTTONUP == lParam)
			{
				hMainMenu = LoadMenu(m_hInstance, MAKEINTRESOURCE(IDR_NIMENU));
				hNotifyIconMenu = GetSubMenu(hMainMenu, 0);
				SetMenuItemBitmaps(hNotifyIconMenu, IDM_ENABLE, 0, GetOpaqueIcon(m_hInstance), NULL);
				SetMenuItemBitmaps(hNotifyIconMenu, IDM_DISABLE, 0, GetTransparentIcon(m_hInstance), NULL);
				GetCursorPos(&pCursor);
				SetForegroundWindow(hWnd);
				TrackPopupMenu(hNotifyIconMenu, TPM_LEFTBUTTON | TPM_RIGHTALIGN, pCursor.x, pCursor.y, 0, hWnd, NULL);				
				PostMessage(hWnd, WM_NULL, 0, 0);
				DestroyMenu(hNotifyIconMenu);
				DestroyMenu(hMainMenu);
			}
			else if (WM_LBUTTONDBLCLK == lParam)
			{
				ShowWindow(m_hMainWnd, SW_SHOWDEFAULT);
			}
			break;
		case WM_COMMAND:
			wmId = LOWORD(wParam);
			switch (wmId)
			{
			case IDM_ENABLE:
				OpacityUtils::ChangeOpacity(true);
				break;
			case IDM_DISABLE:
				OpacityUtils::ChangeOpacity(false);
				break;
			case IDM_EXIT:
				PostQuitMessage(0);
				break;
			}
		case WM_THEMECHANGED:
		case WM_DWMNCRENDERINGCHANGED:
		case WM_DWMCOMPOSITIONCHANGED:
		case WM_DWMCOLORIZATIONCOLORCHANGED:
			OpacityUtils::RestoreOpacity();
			break;
		default:
			return DefWindowProc(hWnd, uMsg, wParam, lParam);
		}
	}
	return 0;
}

CHelperWindow::~CHelperWindow()
{
	if (m_hwnd)
	{
		DestroyWindow(m_hwnd);
		m_hwnd = NULL;
	}
}
